home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / circuits / pcb-1.000 / pcb-1 / pcb-1.3 / draw.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  19KB  |  650 lines

  1. /*
  2.  *                            COPYRIGHT
  3.  *
  4.  *  PCB, interactive printed circuit board design
  5.  *  Copyright (C) 1994,1995 Thomas Nau
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *  Contact addresses for paper mail and Email:
  22.  *  Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
  23.  *  Thomas.Nau@rz.uni-ulm.de
  24.  *
  25.  */
  26.  
  27. static    char    *rcsid = "$Header: /sda6/users/nau/src/pcb/RCS/draw.c,v 2.2 1994/10/03 16:00:05 nau Exp $";
  28.  
  29. /* drawing routines
  30.  */
  31.  
  32. /* ---------------------------------------------------------------------------
  33.  * define TO_SCREEN before macro.h is included from global.h
  34.  */
  35. #define TO_SCREEN(a)    ((a) >> ZoomValue)
  36.  
  37. #include "global.h"
  38.  
  39. #include "crosshair.h"
  40. #include "data.h"
  41. #include "draw.h"
  42. #include "mymem.h"
  43. #include "misc.h"
  44. #include "rotate.h"
  45. #include "select.h"
  46.  
  47. /* ---------------------------------------------------------------------------
  48.  * some local constants
  49.  */
  50. #define    TAN_CONST        0.207106781            /* 0.5*tan(22.5) */
  51.  
  52. /* ---------------------------------------------------------------------------
  53.  * some local types
  54.  */
  55. typedef struct
  56. {
  57.     float    X,
  58.             Y;
  59. } FloatPolyType, *FloatPolyTypePtr;
  60.  
  61. /* ---------------------------------------------------------------------------
  62.  * some local identifiers
  63.  */
  64. static    int                    ZoomValue;        /* zoom and drawable common to */
  65. static    Window                DrawingWindow;    /* all drawing routines */
  66. static    XPoint                Outline[MAX_SIZE+1][8];
  67.  
  68. /* ---------------------------------------------------------------------------
  69.  * some local prototypes
  70.  */
  71. static    void    Redraw(Boolean);
  72. static    void    DrawEverything(void);
  73. static    void    DrawLayer(LayerTypePtr);
  74. static    void    InitSpecialPolygon(void);
  75. static    void    DrawSpecialPolygon(GC, Position, Position, XPoint *);
  76. static    void    DrawPinOrViaLowLevel(PinTypePtr);
  77. static    void    DrawLineLowLevel(LineTypePtr);
  78. static    void    DrawBoxLowLevel(BoxTypePtr);
  79. static    void    DrawTextLowLevel(TextTypePtr);
  80. static    void    DrawPolygonLowLevel(PolygonTypePtr);
  81. static    void    DrawArcLowLevel(ArcTypePtr);
  82. static    void    DrawElementPackageLowLevel(ElementTypePtr Element);
  83.  
  84. /* ---------------------------------------------------------------------------
  85.  * redraws the output area without clearing it
  86.  */
  87. void RedrawOutput(void)
  88. {
  89.     Redraw(False);
  90. }
  91.  
  92. /* ---------------------------------------------------------------------------
  93.  * redraws the output area after clearing it
  94.  */
  95. void ClearAndRedrawOutput(void)
  96. {
  97.     Redraw(True);
  98. }
  99.  
  100. /* ---------------------------------------------------------------------- 
  101.  * redraws all the data
  102.  * all necessary sizes are already set by the viewport widget and
  103.  * by the event handlers
  104.  */
  105. static void Redraw(Boolean ClearWindow)
  106. {
  107.     XEvent    event;
  108.  
  109.         /* check if window already exists */
  110.     if (Output.OutputWindow)
  111.     {
  112.             /* remove all other pending expose events from queue */
  113.         while (XtAppPending(Context))
  114.         {
  115.             XtAppNextEvent(Context, &event);
  116.             if (event.type != Expose ||
  117.                 ((XExposeEvent *) &event)->window != Output.OutputWindow)
  118.                 XtDispatchEvent(&event);
  119.         }
  120.  
  121.             /* switch off crosshair, change drawing window and redraw
  122.              * everything
  123.              */
  124.         HideCrosshair(True);
  125.         SwitchDrawingWindow(PCB->Zoom, Output.OutputWindow);
  126.  
  127.             /* reset the cursor state because of clearing the background
  128.              * of the drawing area
  129.              */
  130.         if (ClearWindow)
  131.         {
  132.             XSetForeground(Dpy, Output.fgGC, Settings.OffLimitColor);
  133.             XFillRectangle(Dpy, DrawingWindow, Output.fgGC,
  134.                 0, 0, MAX_COORD, MAX_COORD);
  135.             XFillRectangle(Dpy, DrawingWindow, Output.bgGC,
  136.                 0, 0, TO_SCREEN(PCB->MaxWidth), TO_SCREEN(PCB->MaxHeight));
  137.             Crosshair.On = False;
  138.         }
  139.  
  140.         DrawEverything();
  141.  
  142.             /* redraw might have come from scrolling the window
  143.              * so we do an update of the cursor position
  144.              */
  145.         MoveCrosshairRelative(0, 0);
  146.         RestoreCrosshair(True);
  147.     }
  148. }
  149.  
  150. /* ----------------------------------------------------------------------
  151.  * setup of zoom and output window for the next drawing operations
  152.  */
  153. void SwitchDrawingWindow(int Zoom, Window OutputWindow)
  154. {
  155.     ZoomValue = Zoom;
  156.     DrawingWindow = OutputWindow;
  157.     InitSpecialPolygon();
  158. }
  159.  
  160. /* ---------------------------------------------------------------------------
  161.  * initializes some identifiers for a new zoom factor and redraws whole screen
  162.  */
  163. static void DrawEverything(void)
  164. {
  165.     Cardinal    i;
  166.  
  167.         /* draw all layers beside the current one */
  168.     for (i = MAX_LAYER-1; i; i--)
  169.         if ((LAYER_ON_STACK(i))->On)
  170.             DrawLayer(LAYER_ON_STACK(i));
  171.  
  172.         /* draw element packages; pins are drawn by RedrawCurrentLayer() */
  173.     if (PCB->ElementOn)
  174.         ELEMENT_LOOP(PCB->Data,
  175.             DrawElementPackage(element);
  176.             DrawElementName(element);
  177.         );
  178.  
  179.         /* make sure that the current layer is always visible */
  180.     RedrawCurrentLayer();
  181.     if (Settings.DrawGrid)
  182.         DrawGrid();
  183. }
  184.  
  185. /* ---------------------------------------------------------------------------
  186.  * redraws the current layer as well as pins and vias
  187.  * the later ones are drawn at last to make the drilling hole visible
  188.  */
  189. void RedrawCurrentLayer(void)
  190. {
  191.     HideCrosshair(True);
  192.     DrawLayer(CURRENT);
  193.  
  194.         /* draw element pins */
  195.     if (PCB->PinOn)
  196.         ELEMENT_LOOP(PCB->Data, DrawElementPins(element););
  197.  
  198.         /* draw vias */
  199.     if (PCB->ViaOn)
  200.         VIA_LOOP(PCB->Data, DrawVia(via););
  201.  
  202.     RestoreCrosshair(True);
  203. }
  204.  
  205. /* ---------------------------------------------------------------------------
  206.  * draws one layer
  207.  */
  208. static void DrawLayer(LayerTypePtr Layer)
  209. {
  210.         /* draw all objects by calling their drawing routines */
  211.     LINE_LOOP(Layer, DrawLine(Layer, line););
  212.     TEXT_LOOP(Layer, DrawText(Layer, text););
  213.     POLYGON_LOOP(Layer, DrawPolygon(Layer, polygon););
  214.  
  215. /* ---------------------------------------------------------------------------
  216.  * initializes some zoom dependend information for pins and lines
  217.  * just to speed up drawing a bit
  218.  */
  219. static void InitSpecialPolygon(void)
  220. {
  221.             int                i, j;
  222.     static    FloatPolyType    p[8] = {{       0.5, -TAN_CONST},
  223.                                     { TAN_CONST,       -0.5},
  224.                                     {-TAN_CONST,       -0.5},
  225.                                     {      -0.5, -TAN_CONST},
  226.                                     {      -0.5,  TAN_CONST},
  227.                                     {-TAN_CONST,        0.5},
  228.                                     { TAN_CONST,        0.5},
  229.                                     {       0.5,  TAN_CONST}};
  230.  
  231.  
  232.         /* loop over maximum number of different sizes */
  233.     for (i = 0; i <= MAX(MAX_PINORVIASIZE, MAX_LINESIZE); i++)
  234.         for (j = 0; j < 8; j++)
  235.         {
  236.             Outline[i][j].x = (p[j].X * TO_SCREEN_X(i));
  237.             Outline[i][j].y = (p[j].Y * TO_SCREEN_Y(i));
  238.         }
  239. }
  240.  
  241. /* ---------------------------------------------------------------------------
  242.  * draws one polygon
  243.  * x and y are already in display coordinates
  244.  * the points are numbered:
  245.  *
  246.  *          5 --- 6
  247.  *         /       \
  248.  *        4         7
  249.  *        |         |
  250.  *        3         0
  251.  *         \       /
  252.  *          2 --- 1
  253.  *
  254.  */
  255. static void DrawSpecialPolygon(GC DrawGC,
  256.     Position X, Position Y, XPoint *PolyPtr)
  257. {
  258.     int        i;
  259.     XPoint    polygon[8];
  260.  
  261.         /* add line offset */
  262.     for (i = 0; i < 8; i++)
  263.     {
  264.         polygon[i].x = X+ PolyPtr[i].x;
  265.         polygon[i].y = Y+ PolyPtr[i].y;
  266.     }
  267.     XFillPolygon(Dpy, DrawingWindow, DrawGC,
  268.         polygon, ENTRIES(polygon), Convex, CoordModeOrigin);
  269. }
  270.  
  271. /* ---------------------------------------------------------------------------
  272.  * lowlevel drawing routine for pins and vias
  273.  */
  274. static void DrawPinOrViaLowLevel(PinTypePtr Ptr)
  275. {
  276.         /* transform X11 specific coord system */
  277.     DrawSpecialPolygon(Output.fgGC, TO_SCREEN_X(Ptr->X), TO_SCREEN_Y(Ptr->Y),
  278.         &Outline[Ptr->Thickness][0]);
  279.     DrawSpecialPolygon(Output.bgGC, TO_SCREEN_X(Ptr->X), TO_SCREEN_Y(Ptr->Y),
  280.         &Outline[Ptr->DrillingHole][0]);
  281. }
  282.  
  283. /* ---------------------------------------------------------------------------
  284.  * lowlevel drawing routine for lines
  285.  */
  286. static void DrawLineLowLevel(LineTypePtr Line)
  287. {
  288.     XSetLineAttributes(Dpy, Output.fgGC,
  289.         TO_SCREEN(Line->Thickness),
  290.         LineSolid, CapRound, JoinRound);
  291.     XDrawLine(Dpy, DrawingWindow, Output.fgGC,
  292.         TO_SCREEN_X(Line->X1), TO_SCREEN_Y(Line->Y1),
  293.         TO_SCREEN_X(Line->X2), TO_SCREEN_Y(Line->Y2));
  294. }
  295.  
  296. /* ---------------------------------------------------------------------------
  297.  * lowlevel drawing routines for boxes
  298.   */
  299. static void DrawBoxLowLevel(BoxTypePtr Box)
  300. {
  301.     Position    x, y;
  302.     Dimension   width, height;
  303.  
  304.         /* convert x and y to window coordinates */
  305.     x = TO_SCREEN_X(Box->X1);
  306.     y = TO_SCREEN_Y(Box->Y1);
  307.     width = TO_SCREEN(Box->X2 -Box->X1);
  308.     height = TO_SCREEN(Box->Y2 -Box->Y1);
  309.     XFillRectangle(Dpy, DrawingWindow, Output.fgGC, x, y, width, height);
  310. }
  311.  
  312. /* ---------------------------------------------------------------------------
  313.  * lowlevel drawing routine for text objects
  314.  */
  315. static void DrawTextLowLevel(TextTypePtr Text)
  316. {
  317.     Position        x = Text->X,
  318.                     y = Text->Y,
  319.                     x0 = 0;            /* initialize to get rid of warnings */
  320.     unsigned char    *string = (unsigned char *) Text->TextString;
  321.     Cardinal        n;
  322.     FontTypePtr        font = &PCB->Font;
  323.  
  324.         /* if text has to be mirrored, get x0 with the unrotated
  325.          * width of the surrounding box (which is the length of the string)
  326.          */
  327.     if (TEST_FLAG(MIRRORFLAG, Text))
  328.     {
  329.         Dimension    width = Text->BoundingBox.X2 -Text->BoundingBox.X1,
  330.                     height = Text->BoundingBox.Y2 -Text->BoundingBox.Y1;
  331.  
  332.         if (Text->Direction == 0 || Text->Direction == 2)
  333.             x0 = Text->X +width/2;
  334.         else
  335.             x0 = Text->X +height/2;
  336.     }
  337.     while (string && *string)
  338.     {
  339.             /* draw lines if symbol is valid and data is present */
  340.         if (*string <= MAX_FONTPOSITION && font->Symbol[*string].Valid)
  341.         {
  342.             LineTypePtr    line = font->Symbol[*string].Line;
  343.             LineType    newline;
  344.  
  345.             for (n = font->Symbol[*string].LineN; n; n--, line++)
  346.             {
  347.                     /* create one line, scale and move it */
  348.                 newline = *line;
  349.                 newline.X1 = newline.X1 *Text->Scale /100 +x;
  350.                 newline.Y1 = newline.Y1 *Text->Scale /100 +y;
  351.                 newline.X2 = newline.X2 *Text->Scale /100 +x;
  352.                 newline.Y2 = newline.Y2 *Text->Scale /100 +y;
  353.                 newline.Thickness = newline.Thickness *Text->Scale /100;
  354.  
  355.                     /* do some mirroring and rotations */
  356.                 if (TEST_FLAG(MIRRORFLAG, Text))
  357.                 {
  358.                     newline.X1 = 2*x0 -newline.X1;
  359.                     newline.X2 = 2*x0 -newline.X2;
  360.                 }
  361.                 RotateLineLowLevel(&newline,Text->X,Text->Y,Text->Direction);
  362.                 DrawLineLowLevel(&newline);
  363.             }
  364.                 /* move on to next cursor position */
  365.             x += ((font->Symbol[*string].Width +font->Symbol[*string].Delta)
  366.                 *Text->Scale /100);
  367.         }
  368.         else
  369.         {
  370.                 /* the default symbol is a filled box */
  371.             BoxType    defaultsymbol = PCB->Font.DefaultSymbol;
  372.  
  373.             defaultsymbol.X1 = defaultsymbol.X1 *Text->Scale /100 +x;
  374.             defaultsymbol.Y1 = defaultsymbol.Y1 *Text->Scale /100 +y;
  375.             
  376.  
  377.                 /* do some mirroring and rotations */
  378.             if (TEST_FLAG(MIRRORFLAG, Text))
  379.                 defaultsymbol.X1 = 2*x0 -defaultsymbol.X1 -defaultsymbol.X2;
  380.             RotateBoxLowLevel(&defaultsymbol,Text->X,Text->Y, Text->Direction);
  381.             DrawBoxLowLevel(&defaultsymbol);
  382.  
  383.                 /* move on to next cursor position */
  384.             x += ((defaultsymbol.X2 -defaultsymbol.X1)/4 *Text->Scale /100);
  385.         }
  386.         string++;
  387.     }
  388. }
  389.  
  390. /* ---------------------------------------------------------------------------
  391.  * lowlevel drawing routine for polygons
  392.  */
  393. static void DrawPolygonLowLevel(PolygonTypePtr Polygon)
  394. {
  395.     static    XPoint        *data = NULL;    /* tmp pointer */
  396.     static    Cardinal    max = 0;
  397.  
  398.         /* allocate memory for data with screen coordinates */
  399.     if (Polygon->PointN > max)
  400.     {
  401.         max = Polygon->PointN;
  402.         data = (XPoint *) MyRealloc(data, max *sizeof(XPoint),
  403.             "DrawPolygonLowLevel()");
  404.     }
  405.  
  406.         /* copy data to tmp array and convert it to screen coordinates */
  407.     POLYGONPOINT_LOOP(Polygon,
  408.         data[n].x = TO_SCREEN_X(point->X);
  409.         data[n].y = TO_SCREEN_Y(point->Y);
  410.     );
  411.     XFillPolygon(Dpy, DrawingWindow, Output.fgGC,
  412.         data, Polygon->PointN, Complex, CoordModeOrigin);
  413. }
  414.  
  415. /* ---------------------------------------------------------------------------
  416.  * lowlevel routine to element arcs
  417.  */
  418. static void DrawArcLowLevel(ArcTypePtr Arc)
  419. {
  420.         /* angles have to be converted to X11 notation */
  421.     XSetLineAttributes(Dpy, Output.fgGC,
  422.         TO_SCREEN(Arc->Thickness), LineSolid, CapRound, JoinRound);
  423.     XDrawArc(Dpy, DrawingWindow, Output.fgGC,
  424.         TO_SCREEN_X(Arc->X -Arc->Width), TO_SCREEN_Y(Arc->Y -Arc->Height),
  425.         TO_SCREEN(2*Arc->Width), TO_SCREEN(2*Arc->Height),
  426.         (Arc->StartAngle +180) *64, Arc->Delta *64);
  427. }
  428.  
  429. /* ---------------------------------------------------------------------------
  430.  * draws the package of an element
  431.  */
  432. static void DrawElementPackageLowLevel(ElementTypePtr Element)
  433. {
  434.         /* draw lines, arcs, text and pins */
  435.     ELEMENTLINE_LOOP(Element, DrawLineLowLevel(line););
  436.     ARC_LOOP(Element, DrawArcLowLevel(arc););
  437. }
  438.  
  439. /* ---------------------------------------------------------------------------
  440.  * draw a via object
  441.  */
  442. void DrawVia(PinTypePtr Via)
  443. {
  444.     if (TEST_FLAG(SELECTEDFLAG, Via))
  445.         XSetForeground(Dpy, Output.fgGC, PCB->SelectedColor);
  446.     else
  447.         if (TEST_FLAG(FOUNDFLAG, Via))
  448.             XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
  449.         else
  450.             XSetForeground(Dpy, Output.fgGC, PCB->ViaColor);
  451.     DrawPinOrViaLowLevel(Via);
  452. }
  453.  
  454. /* ---------------------------------------------------------------------------
  455.  * draw a pin object
  456.  */
  457. void DrawPin(PinTypePtr Pin)
  458. {
  459.     if (TEST_FLAG(SELECTEDFLAG, Pin))
  460.         XSetForeground(Dpy, Output.fgGC, PCB->SelectedColor);
  461.     else
  462.         if (TEST_FLAG(FOUNDFLAG, Pin))
  463.             XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
  464.         else
  465.             XSetForeground(Dpy, Output.fgGC, PCB->PinColor);
  466.     DrawPinOrViaLowLevel(Pin);
  467. }
  468.  
  469. /* ---------------------------------------------------------------------------
  470.  * draws a line on a layer
  471.  */
  472. void DrawLine(LayerTypePtr Layer, LineTypePtr Line)
  473. {
  474.     if (TEST_FLAG(SELECTEDFLAG, Line))
  475.         XSetForeground(Dpy, Output.fgGC, PCB->SelectedColor);
  476.     else
  477.         if (TEST_FLAG(FOUNDFLAG, Line))
  478.             XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
  479.         else
  480.             XSetForeground(Dpy, Output.fgGC, Layer->Color);
  481.     DrawLineLowLevel(Line);
  482. }
  483.  
  484. /* ---------------------------------------------------------------------------
  485.  * draws a text on a layer
  486.  */
  487. void DrawText(LayerTypePtr Layer, TextTypePtr Text)
  488. {
  489.     if (TEST_FLAG(SELECTEDFLAG, Text))
  490.         XSetForeground(Dpy, Output.fgGC, PCB->SelectedColor);
  491.     else
  492.         XSetForeground(Dpy, Output.fgGC, Layer->Color);
  493.     DrawTextLowLevel(Text);
  494. }
  495.  
  496. /* ---------------------------------------------------------------------------
  497.  * draws a polygon on a layer
  498.  */
  499. void DrawPolygon(LayerTypePtr Layer, PolygonTypePtr Polygon)
  500. {
  501.     if (TEST_FLAG(SELECTEDFLAG, Polygon))
  502.         XSetForeground(Dpy, Output.fgGC, PCB->SelectedColor);
  503.     else
  504.         if (TEST_FLAG(FOUNDFLAG, Polygon))
  505.             XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
  506.         else
  507.             XSetForeground(Dpy, Output.fgGC, Layer->Color);
  508.     DrawPolygonLowLevel(Polygon);
  509. }
  510.  
  511. /* ---------------------------------------------------------------------------
  512.  * draws an element
  513.  */
  514. void DrawElement(ElementTypePtr Element)
  515. {
  516.         /* set color and draw lines, arcs, text and pins */
  517.     if (TEST_FLAG(SELECTEDFLAG, Element))
  518.         XSetForeground(Dpy, Output.fgGC, PCB->SelectedColor);
  519.     else
  520.         XSetForeground(Dpy, Output.fgGC, PCB->ElementColor);
  521.     DrawElementPackageLowLevel(Element);
  522.     DrawElementName(Element);
  523.     DrawElementPins(Element);
  524.  
  525. /* ---------------------------------------------------------------------------
  526.  * draws the name of an element
  527.  */
  528. void DrawElementName(ElementTypePtr Element)
  529. {
  530.     if (TEST_FLAG(SELECTEDFLAG, &ELEMENT_TEXT(PCB, Element)))
  531.         XSetForeground(Dpy, Output.fgGC, PCB->SelectedColor);
  532.     else
  533.         XSetForeground(Dpy, Output.fgGC, PCB->ElementColor);
  534.     DrawTextLowLevel(&ELEMENT_TEXT(PCB, Element));
  535. }
  536.  
  537. /* ---------------------------------------------------------------------------
  538.  * draws the package of an element
  539.  */
  540. void DrawElementPackage(ElementTypePtr Element)
  541. {
  542.         /* set color and draw lines, arcs, text and pins */
  543.     if (TEST_FLAG(SELECTEDFLAG, Element))
  544.         XSetForeground(Dpy, Output.fgGC, PCB->SelectedColor);
  545.     else
  546.         XSetForeground(Dpy, Output.fgGC, PCB->ElementColor);
  547.     DrawElementPackageLowLevel(Element);
  548. }
  549.  
  550. /* ---------------------------------------------------------------------------
  551.  * draw pins of an element
  552.  */
  553. void DrawElementPins(ElementTypePtr Element)
  554. {
  555.     PIN_LOOP(Element, DrawPin(pin););
  556. }
  557.  
  558. /* ---------------------------------------------------------------------------
  559.  * erase a via object
  560.  */
  561. void EraseVia(PinTypePtr Via)
  562. {
  563.     XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
  564.     DrawPinOrViaLowLevel(Via);
  565. }
  566.  
  567. /* ---------------------------------------------------------------------------
  568.  * erase a pin object
  569.  */
  570. void ErasePin(PinTypePtr Pin)
  571. {
  572.     XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
  573.     DrawPinOrViaLowLevel(Pin);
  574. }
  575.  
  576. /* ---------------------------------------------------------------------------
  577.  * erases a line on a layer
  578.  */
  579. void EraseLine(LineTypePtr Line)
  580. {
  581.     XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
  582.     DrawLineLowLevel(Line);
  583. }
  584.  
  585. /* ---------------------------------------------------------------------------
  586.  * erases a text on a layer
  587.  */
  588. void EraseText(TextTypePtr Text)
  589. {
  590.     XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
  591.     DrawTextLowLevel(Text);
  592. }
  593.  
  594. /* ---------------------------------------------------------------------------
  595.  * erases a polygon on a layer
  596.  */
  597. void ErasePolygon(PolygonTypePtr Polygon)
  598. {
  599.     XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
  600.     DrawPolygonLowLevel(Polygon);
  601. }
  602.  
  603. /* ---------------------------------------------------------------------------
  604.  * erases an element
  605.  */
  606. void EraseElement(ElementTypePtr Element)
  607. {
  608.         /* set color and draw lines, arcs, text and pins */
  609.     XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
  610.     ELEMENTLINE_LOOP(Element, DrawLineLowLevel(line););
  611.     ARC_LOOP(Element, DrawArcLowLevel(arc););
  612.     DrawTextLowLevel(&ELEMENT_TEXT(PCB, Element));
  613.     PIN_LOOP(Element, DrawPinOrViaLowLevel(pin););
  614.  
  615. /* ---------------------------------------------------------------------------
  616.  * erases the name of an element
  617.  */
  618. void EraseElementName(ElementTypePtr Element)
  619. {
  620.     XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
  621.     DrawTextLowLevel(&ELEMENT_TEXT(PCB, Element));
  622. }
  623.  
  624. /* ---------------------------------------------------------------------------
  625.  * draws grid points if the distance is >= MIN_GRID_DISTANCE
  626.  */
  627. void DrawGrid(void)
  628. {
  629.     Position    minx, miny,
  630.                 maxx, maxy,
  631.                 x, y;
  632.  
  633.     if (TO_SCREEN(PCB->Grid) >= MIN_GRID_DISTANCE)
  634.     {
  635.         minx = TO_PCB_X(Output.OffsetX);
  636.         miny = TO_PCB_Y(Output.OffsetY);;
  637.         maxx = TO_PCB_X(Output.OffsetX +Output.Width);
  638.         maxy = TO_PCB_Y(Output.OffsetY +Output.Height);
  639.         maxx = MIN((Dimension) maxx, PCB->MaxWidth);
  640.         maxy = MIN((Dimension) maxy, PCB->MaxHeight);
  641.         for (y = miny; y <= maxy; y += PCB->Grid)
  642.             for (x = minx; x <= maxx; x += PCB->Grid)
  643.                 XDrawPoint(Dpy, Output.OutputWindow, Crosshair.AttachGC,
  644.                     TO_SCREEN_X(GRIDFIT_X(x)), TO_SCREEN_Y(GRIDFIT_Y(y)));
  645.     }
  646. }
  647.